← Back to Frontend System Design Blogs

Shared Module – Low Level Design

2025-06-29📖 3 min read

Share:

🔧 Step 7: Shared Module – Low Level Design (LLD)

This document details the implementation of the shared module, which provides common UI components, directives, and pipes used throughout the app.


📦 Module Structure

src/
├── app/
│   └── shared/
│       ├── components/
│       │   ├── button/
│       │   ├── modal/
│       │   ├── loader/
│       │   └── snackbar/
│       ├── directives/
│       │   ├── autofocus.directive.ts
│       │   └── permission.directive.ts
│       ├── pipes/
│       │   ├── currency-format.pipe.ts
│       │   └── truncate.pipe.ts
│       ├── services/
│       │   └── snackbar.service.ts
│       ├── shared.module.ts

🧱 Component Breakdown

🔘 ButtonComponent

  • Reusable button with configurable styles (primary, secondary, disabled states)
  • Emits click events to parent components

🗔 ModalComponent

  • Generic modal dialog component with customizable header, body, footer slots
  • Supports close/cancel actions

⏳ LoaderComponent

  • Displays a loading spinner overlay
  • Used to indicate asynchronous operations in progress

🔔 SnackbarComponent

  • Shows brief toast/snackbar messages for feedback (success, error, info)
  • Auto-dismisses after timeout or on user action

⚙️ Directives

🔍 AutofocusDirective

  • Automatically sets focus to an input element when the component loads

🔐 PermissionDirective

  • Conditionally shows/hides elements based on user permissions or roles

🔄 Pipes

💰 CurrencyFormatPipe

  • Formats numeric values as localized currency strings

✂️ TruncatePipe

  • Truncates long text strings and appends ellipsis () for UI consistency

🧪 Services

SnackbarService

  • Controls display of snackbars across the app
  • Provides methods to show success, error, and info messages
@Injectable({ providedIn: "root" })
export class SnackbarService {
  private snackbarSubject = new Subject<SnackbarMessage>();

  get messages$(): Observable<SnackbarMessage> {
    return this.snackbarSubject.asObservable();
  }

  showSuccess(message: string): void {
    this.snackbarSubject.next({ message, type: "success" });
  }

  showError(message: string): void {
    this.snackbarSubject.next({ message, type: "error" });
  }

  showInfo(message: string): void {
    this.snackbarSubject.next({ message, type: "info" });
  }
}

export interface SnackbarMessage {
  message: string;
  type: "success" | "error" | "info";
}

📐 Module Definition

@NgModule({
  declarations: [
    ButtonComponent,
    ModalComponent,
    LoaderComponent,
    SnackbarComponent,
    AutofocusDirective,
    PermissionDirective,
    CurrencyFormatPipe,
    TruncatePipe,
  ],
  imports: [CommonModule],
  exports: [
    ButtonComponent,
    ModalComponent,
    LoaderComponent,
    SnackbarComponent,
    AutofocusDirective,
    PermissionDirective,
    CurrencyFormatPipe,
    TruncatePipe,
  ],
})
export class SharedModule {}

✅ Responsibilities Summary

Part Responsibility
ButtonComponent Reusable button UI
ModalComponent Generic modal dialogs
LoaderComponent Loading indicators
SnackbarComponent Toast/snackbar feedback
AutofocusDirective Auto-focus inputs
PermissionDirective Conditional UI rendering based on permissions
CurrencyFormatPipe Currency formatting
TruncatePipe Text truncation
SnackbarService Centralized snackbar management